package org.example.main.multi_threading;

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * 开启多线程方式：实现Callable接口
 * @Author: WangShengJie
 * @Date: 2025/6/8
 */
public class CallableDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**
         * 实现Callable接口
         *
         * 当使用 ExecutorService 的submit()方法提交一个Callable任务时，
         * ExecutorService会负责启动一个新的线程来执行这个任务，并返回一个 Future 对象。
         * Future对象代表了异步计算的结果，可以通过它来获取执行结果、检查是否计算完成、取消任务的执行等‌
         */
        //方式1
        //声明10个线程
        System.out.println("开始");
        long start = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        List<Future<Object>> futures = new ArrayList<>();
        //开启10条线程
        for (int i = 0; i < 10; i++) {
            //实现callable接口
            int cunt = i;
            Callable<Object> callable = new Callable<Object>() {
                @Override
                public Object call() throws Exception {
//                    System.out.println("实现callable接口");
                    Thread.sleep(4000);     //睡4s
                    return "实现callable接口：当前为第：" + cunt + "条线程执行结果。当前线程：" + Thread.currentThread();
                }
            };
            Future<Object> future = executorService.submit(callable);
            futures.add(future);
        }
        //获取执行结果
        for (Future<Object> future : futures) {
            //future.get(10, TimeUnit.SECONDS)‌：尝试获取任务结果，最多等待10秒，超时抛出TimeoutException
            //get()会阻塞线程的创建，所以这里也需要异步获取
            System.out.println(future.get());
        }
        executorService.shutdown();
        long end = System.currentTimeMillis();
        System.out.println("结束。用时【" + (end - start) + "毫秒】");

//        //方式二
        List<FutureTask<Object>> futureTasks = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //1、重写·callable中call()方法
            Callable<Object> callable = new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    System.out.println("***"+Thread.currentThread());
                    return "callable接口开启多线程方式二";
                }
            };
            //2、封装成一个 FutureTask 对象
            FutureTask<Object> futureTask = new FutureTask<>(callable);
            futureTasks.add(futureTask);
            //3、实例化一个Thread
            Thread thread = new Thread(futureTask);
            //4、start()开启多线程
            thread.start();
        }
        for (FutureTask<Object> futureTask : futureTasks) {
            System.out.println(futureTask.get());
        }
    }
}
